from sqlalchemy import or_
from app import db
from app.models.menu import Menu


class MenuService:
    """菜单服务层"""
    
    @staticmethod
    def get_list(page=1, per_page=10, keyword=None, visible=None, status=None):
        """获取菜单列表"""
        query = Menu.query
        
        # 关键词搜索
        if keyword:
            query = query.filter(Menu.name.like(f'%{keyword}%'))
        
        # 可见性筛选
        if visible is not None:
            query = query.filter(Menu.visible == visible)
        
        # 状态筛选
        if status is not None:
            query = query.filter(Menu.status == status)
        
        # 按排序字段和创建时间排列
        query = query.order_by(Menu.order_num, Menu.create_time.desc())
        
        return query, page, per_page
    
    @staticmethod
    def get_tree(keyword=None, visible=None, status=None):
        """获取菜单树形结构（管理员用，返回所有菜单）"""
        query = Menu.query
        
        # 应用筛选条件
        if keyword:
            query = query.filter(Menu.name.like(f'%{keyword}%'))
        
        if visible is not None:
            query = query.filter(Menu.visible == visible)
        
        if status is not None:
            query = query.filter(Menu.status == status)
        else:
            # 默认只显示启用状态的菜单
            query = query.filter(Menu.status == True)
        
        # 如果有筛选条件，返回平铺结构
        if keyword or visible is not None or status is not None:
            menus = query.order_by(Menu.order_num).all()
            return [menu.to_dict() for menu in menus]
        
        # 没有筛选条件时返回树形结构
        menus = query.filter_by(parent_id=None).order_by(Menu.order_num).all()
        return [menu.to_tree_dict() for menu in menus]
    
    @staticmethod
    def get_tree_for_permission():
        """获取权限配置专用的菜单树结构（返回所有启用的菜单）"""
        # 获取所有启用的根菜单
        root_menus = Menu.query.filter_by(
            parent_id=None, 
            status=True
        ).order_by(Menu.order_num).all()
        
        # 构建包含权限信息的菜单树
        result = []
        for menu in root_menus:
            menu_dict = menu.to_tree_dict_for_permission()
            result.append(menu_dict)
        
        return result
    
    @staticmethod
    def get_tree_by_role(role_id):
        """根据角色获取菜单树形结构"""
        from app.models.role import RoleMenu
        
        # 获取角色有权限的菜单ID列表
        role_menu_ids = db.session.query(RoleMenu.menu_id)\
                                 .filter_by(role_id=role_id).all()
        menu_ids = [rm.menu_id for rm in role_menu_ids]
        
        if not menu_ids:
            return []
        
        # 获取有权限的根菜单
        root_menus = Menu.query.filter(
            Menu.id.in_(menu_ids),
            Menu.status == True,
            Menu.parent_id == None
        ).order_by(Menu.order_num).all()
        
        return [menu.to_tree_dict_with_permission(menu_ids) for menu in root_menus]
    
    @staticmethod
    def get_by_id(menu_id):
        """根据ID获取菜单"""
        return Menu.query.get(menu_id)
    
    @staticmethod
    def create(data):
        """创建菜单"""
        menu = Menu()
        menu.parent_id = data.get('parent_id')
        menu.name = data.get('name')
        menu.icon = data.get('icon')
        menu.order_num = data.get('order_num', 0)
        menu.path = data.get('path')
        menu.visible = data.get('visible', True)
        menu.status = data.get('status', True)
        
        db.session.add(menu)
        db.session.commit()
        return menu
    
    @staticmethod
    def update(menu_id, data):
        """更新菜单"""
        menu = Menu.query.get(menu_id)
        if not menu:
            return None
        
        menu.parent_id = data.get('parent_id', menu.parent_id)
        menu.name = data.get('name', menu.name)
        menu.icon = data.get('icon', menu.icon)
        menu.order_num = data.get('order_num', menu.order_num)
        menu.path = data.get('path', menu.path)
        menu.visible = data.get('visible', menu.visible)
        menu.status = data.get('status', menu.status)
        
        db.session.commit()
        return menu
    
    @staticmethod
    def delete(menu_id):
        """删除菜单"""
        menu = Menu.query.get(menu_id)
        if not menu:
            return False
        
        # 检查是否有子菜单
        if menu.children:
            return False, "该菜单存在子菜单，无法删除"
        
        db.session.delete(menu)
        db.session.commit()
        return True, "删除成功"
    
    @staticmethod
    def get_parent_options():
        """获取父菜单选项"""
        menus = Menu.query.filter_by(status=True).all()
        return [{'id': menu.id, 'name': menu.name} for menu in menus] 